const util = require("./util");
/**
 * 事件循环队列
 */
class EventLoop {
  constructor(arg = {}) {
    const { parallel, list } = arg;
    if (list && Array.isArray(list)) {
      list.forEach((e) => {
        if (!util.isFunction(e)) {
          throw Error(`${fn}不是function`);
        }
      });
    }

    // 并行
    this.parallel = parallel || false;
    // 执行状态
    this.padding = false;
    // 事件池
    this.list = list || [];
    // 完成回调
    this.endEvet = [];
  }

  /**
   * 开始任务
   */
  async start() {
    this.parallel ? this.parallelRun() : this.serialRull();
  }

  /**
   * 获取长度
   * @returns
   */
  getSize() {
    return this.list.length;
  }
  /**
   * 获取下个任务
   * @returns
   */
  getFu() {
    if (this.list.length) {
      return this.list.shift();
    }
    return null;
  }
  /**
   * 添加任务并自动执行
   * @param {*} fn
   */
  add(fn) {
    if (!util.isFunction(fn)) throw Error(`${fn}不是function`);
    this.list.push(fn);
  }
  /**
   * 串行
   */
  async serialRull() {
    let i = this.getSize();
    while(i > 0){
       this.padding = true;
      const fn = this.getFu();
      if (fn) {
        await fn();
      }
      this.padding = false;
      i = this.getSize();
    }
    // 执行完毕
    this.endEvet.forEach((e) => e());
  }
  /**
   * 并行
   * @returns
   */
  parallelRun() {
    if (this.getSize()) {
      this.padding = true;
      const list =[] 
      this.list.forEach(e=>{
        list.push(e())
      })
      Promise.all(list).then(() => {
        this.padding = false;
        // 执行完毕
        this.endEvet.forEach((e) => e());
      });
    } else {
      // 执行完毕
      this.endEvet.forEach((e) => e());
    }
  }
  //end 事件
  onEnd(callback) {
    this.endEvet.push(callback);
  }
}

module.exports = EventLoop;
